package com.dawnling.androidutils.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.SizeUtils;

/**
 * Des: 图片裁剪上层视图
 * Created by dawnLing on 2020/4/26
 */
public class ChooseArea1 extends View {

    private Context _context;
    private Paint paintDrawCircle;
    private Paint paintDrawLine;
    private boolean shouldIntercept;

    public ChooseArea1(Context context) {
        super(context);
        _context = context;
        init();
    }

    public ChooseArea1(Context context, AttributeSet attrs) {
        super(context, attrs);
        _context = context;
        init();
    }

    public ChooseArea1(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        _context = context;
        init();
    }

    private void init() {
        // 四个角的外圆圆圈的画笔
        paintDrawCircle = new Paint();
        paintDrawCircle.setStyle(Paint.Style.FILL);
        paintDrawCircle.setStrokeWidth(SizeUtils.dp2px(1));
        paintDrawCircle.setColor(Color.argb(255, 91, 180, 59));
        paintDrawCircle.setAntiAlias(true);

        // 全透明区边框的画笔
        paintDrawLine = new Paint();
        paintDrawLine.setStyle(Paint.Style.STROKE);
        paintDrawLine.setStrokeWidth(SizeUtils.dp2px(1));
        paintDrawLine.setColor(Color.argb(255, 91, 180, 59));
        paintDrawLine.setAntiAlias(true);
    }

    // 这4个点就是代表着4个控制点，顺序是这样的：
    /**
     * 0*********1
     * *         *
     * *         *
     * 3*********2
     */
    private Point[] p = null;
    private IPointChangeListener pointChangeListener;

    public void setPointChangeListener(IPointChangeListener listener) {
        this.pointChangeListener = listener;
    }

    private void onPointChanged() {
        if (pointChangeListener != null) pointChangeListener.change(p);
    }

    /**
     * 初始化裁剪框位置，即传入坐标点
     */
    public void setRegion(Point p0, Point p1, Point p2, Point p3) {
        p = new Point[4];
        p[0] = new Point(p0);
        p[1] = new Point(p1);
        p[2] = new Point(p2);
        p[3] = new Point(p3);
    }

    private int currentPoint = -1;
    private View bottomView = null;

    public void setBottomView(View bottomView) {
        this.bottomView = bottomView;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // 对于超出边界的动作进行纠正， 这里的width和height在onDraw中已经初始化
        checkAndCorrect(event, width, height);
        switch (event.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:
                LogUtils.i("ACTION_DOWN");
                int index = findTheCoveredPoint(event.getX(), event.getY());
                if (index == -1) {
                    shouldIntercept = false;
                    return false;
                }
                shouldIntercept = true;
                currentPoint = index;
                break;
            case MotionEvent.ACTION_MOVE:
                if (currentPoint == -1)
                    return false;
                switch (currentPoint) {
                    case 0:
                        resetXY(event);
                        p[3].x = p[currentPoint].x;
                        p[1].y = p[currentPoint].y;
                        break;
                    case 3:
                        resetXY(event);
                        p[0].x = p[currentPoint].x;
                        p[2].y = p[currentPoint].y;
                        break;
                    case 1:
                        resetXY(event);
                        p[2].x = p[currentPoint].x;
                        p[0].y = p[currentPoint].y;
                        break;
                    case 2:
                        resetXY(event);
                        p[1].x = p[currentPoint].x;
                        p[3].y = p[currentPoint].y;
                        break;
                    default:
                        break;
                }
                LogUtils.i("move x=" + event.getX() + "y=" + event.getY());
                break;
            case MotionEvent.ACTION_UP:
                currentPoint = -1;
                onPointChanged();
                break;
            case MotionEvent.ACTION_POINTER_DOWN:
            case MotionEvent.ACTION_POINTER_UP:
                currentPoint = -1;
                return false;
            default:
                return false;
        }
        LogUtils.i("move x=" + event.getX() + "y=" + event.getY());
        invalidate();
        return true;
    }

    private void checkAndCorrect(MotionEvent event, int width, int height) {
        float x = event.getX(), y = event.getY();
        if (x < 0)
            x = 0;
        else if (x > width)
            x = width;

        if (y < 0)
            y = 0;
        else if (y > height)
            y = height;
        event.setLocation(x, y);
    }

    //重新设置圆点的位置
    private void resetXY(MotionEvent event) {
        p[currentPoint].x = (int) event.getX();
        p[currentPoint].y = (int) event.getY();
    }

    // 与控制点相邻80个像素点就选中，因为我的手机是1080p的分辨率，如果分辨率不同这里最好设置成不同的数值
    private static final int BOUND = 80;

    // 计算出当前手指触控的是哪个控制点
    private int findTheCoveredPoint(float x, float y) {
        if (p == null)
            return -1;
        for (int i = 0; i < p.length; i++) {
            if (Math.sqrt((p[i].x - x) * (p[i].x - x) + (p[i].y - y) * (p[i].y - y)) - BOUND <= 0) {
                return i;
            }
        }
        return -1;
    }

    private int width, height;
    private boolean getParams = false;

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (!getParams) {
            if (bottomView == null)
                throw new IllegalStateException("you must set the bottom view !");
            width = bottomView.getWidth();
            height = bottomView.getHeight();
            getParams = true;
        }
        // 画出中间全透明区域的边框
        Path path = getPath(p[0], p[1], p[2], p[3]);
        canvas.drawPath(path, paintDrawLine);
        // 画出四个角的小圈
        for (int i = 0; i < p.length; i++) {
            canvas.drawCircle(p[i].x, p[i].y, SizeUtils.dp2px(8), paintDrawCircle);
        }
    }

    private Path getPath(Point... points) {
        Path path = new Path();
        path.moveTo(points[0].x, points[0].y);
        for (int i = 1; i < points.length; i++) {
            path.lineTo(points[i].x, points[i].y);
        }
        path.close();
        return path;
    }

    public interface IPointChangeListener {
        void change(Point[] points);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if (shouldIntercept) {
            getParent().requestDisallowInterceptTouchEvent(true);
        }
        return super.dispatchTouchEvent(ev);
    }
}
